package com.cpp.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cpp.common.constant.ModuleConstant;
import com.cpp.common.constant.redis.CsOpRedisConstant;
import com.cpp.common.constant.redis.OperationConstant;
import com.cpp.common.enums.AnswerStatus;
import com.cpp.common.enums.UserRoleEnum;
import com.cpp.pojo.pojo.*;
import com.cpp.pojo.vo.view.OptimizeCourseVO;
import com.cpp.pojo.vo.view.StudentLearningEffectVO;
import com.cpp.pojo.vo.user.UserDataVO;
import com.cpp.pojo.vo.user.UserUseDataVO;
import com.cpp.server.aspect.annotation.UserRole;
import com.cpp.server.context.UserHolder;
import com.cpp.server.mapper.*;
import com.cpp.server.service.AdminViewService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class AdminViewServiceImpl implements AdminViewService {
    private final OperationLogMapper operationLogMapper;
    private final TimeLogMapper timeLogMapper;
    private final ChatClient learnPathAIChatClient;
    private final SubjectMapper subjectMapper;
    private final CourseMapper courseMapper;
    private final ExamRecordMapper examRecordMapper;
    private final ExamMapper examMapper;
    private final AnswerRecordMapper answerRecordMapper;
    private final KnowledgeMapper knowledgeMapper;
    private final StringRedisTemplate stringRedisTemplate;


    @UserRole(roles = {UserRoleEnum.ADMIN})
    public UserUseDataVO teacherDayUseData() {
        //查询模块操作记录
        UserUseDataVO userUseDataVO = operationLogMapper.countTeacherDayUse();
        return dataProcess(userUseDataVO, ModuleConstant.TEACHER_MODULE_LIST);
    }

    @UserRole(roles = {UserRoleEnum.ADMIN})
    public UserUseDataVO teacherWeekUseData() {
        //查询模块操作记录
        UserUseDataVO userUseDataVO = operationLogMapper.countTeacherWeekUse();
        return dataProcess(userUseDataVO, ModuleConstant.TEACHER_MODULE_LIST);
    }

    @UserRole(roles = {UserRoleEnum.ADMIN})
    public UserUseDataVO studentDayUseData() {
        //查询模块操作记录
        UserUseDataVO userUseDataVO = operationLogMapper.countStudentDayUse();
        return dataProcess(userUseDataVO, ModuleConstant.STUDENT_MODULE_LIST);
    }

    @UserRole(roles = {UserRoleEnum.ADMIN})
    public UserUseDataVO studentWeekUseData() {
        //查询模块操作记录
        UserUseDataVO userUseDataVO = operationLogMapper.countStudentWeekUse();
        return dataProcess(userUseDataVO, ModuleConstant.STUDENT_MODULE_LIST);
    }

    private UserUseDataVO dataProcess(UserUseDataVO userUseDataVO, List<String> moduleList) {
        //填充没有的模块
        if (userUseDataVO==null){
            userUseDataVO = UserUseDataVO.builder()
                    .startDate(LocalDateTime.now().minusDays(7))
                    .endDate(LocalDateTime.now())
                    .totalUseCount(0L)
                    .data(new ArrayList<>())
                    .build();
        }
        List<UserDataVO> userDataVOs = userUseDataVO.getData();
        List<String> plate = userDataVOs.stream().map(UserDataVO::getPlate).toList();
        List<String> teacherModuleList = new ArrayList<>(moduleList);
        teacherModuleList.removeAll(plate);
        if (!teacherModuleList.isEmpty()) {
            for (String teacherModule : teacherModuleList) {
                userDataVOs.add(UserDataVO.builder()
                        .plate(teacherModule)
                        .useCount(0L)
                        .build());
                userUseDataVO.setData(userDataVOs);
            }
        }
        return userUseDataVO;
    }

    //    备课与修正耗时
    @UserRole(roles = {UserRoleEnum.ADMIN})
    public Map<String, Double> chapterEfficiency() {
        //备课与修正耗时、课后练习设计与修正n

        LambdaQueryWrapper<TimeLog> operationLogWrapper = new LambdaQueryWrapper<>();
        operationLogWrapper.eq(TimeLog::getFunctionName, OperationConstant.generateChapter);
        //近七天
        LocalDateTime now = LocalDateTime.now();
        //减七天
        LocalDateTime beforeSevenDays = now.minusDays(7);
        operationLogWrapper.between(TimeLog::getStartTime, beforeSevenDays, now);
        List<TimeLog> timeLogs = timeLogMapper.selectList(operationLogWrapper);

        Map<String, Double> map = new HashMap<>();
        double sumSecond = 0.0;
        if (timeLogs.isEmpty()){
            timeLogs.add(TimeLog.builder()
                    .duration(0.0
                    ).build());
        }
        double maxSecond = timeLogs.get(0).getDuration();
        double minSecond = timeLogs.get(0).getDuration();

        //算总时间，且拿到最长时间，和最小时间
        for (TimeLog timeLog : timeLogs) {
            if (timeLog.getDuration() == null) {
                continue;
            }
            if (timeLog.getDuration() > maxSecond) {
                maxSecond = timeLog.getDuration();
            }
            if (timeLog.getDuration() < minSecond) {
                minSecond = timeLog.getDuration();
            }
            sumSecond += timeLog.getDuration();
        }
        //转秒为分
        double sumMinute = sumSecond / 60;
        double maxMinute = maxSecond / 60;
        double minMinute = minSecond / 60;
        double averageMinute = sumMinute / timeLogs.size();
        if (!timeLogs.isEmpty()) {
            //平均分钟
            map.put("averageMinute", averageMinute);
            map.put("maxMinute", maxMinute);
            map.put("minMinute", minMinute);
            map.put("sumMinute", sumMinute);
        }
        return map;
    }

    //    课后练习设计与修正耗时
    @UserRole(roles = {UserRoleEnum.ADMIN})
    public Map<String, Double> examEfficiency() {

        LambdaQueryWrapper<TimeLog> operationLogWrapper = new LambdaQueryWrapper<>();
        operationLogWrapper.eq(TimeLog::getFunctionName, OperationConstant.generatePractice);
        //近七天
        LocalDateTime now = LocalDateTime.now();
        //减七天
        LocalDateTime beforeSevenDays = now.minusDays(7);
        operationLogWrapper.between(TimeLog::getStartTime, beforeSevenDays, now);
        List<TimeLog> timeLogs = timeLogMapper.selectList(operationLogWrapper);

        Map<String, Double> map = new HashMap<>();
        double sumSecond = 0.0;
        if (timeLogs.isEmpty()){
            timeLogs.add(TimeLog.builder()
                    .duration(0.0
                    ).build());
        }
        double maxSecond = timeLogs.get(0).getDuration();
        double minSecond = timeLogs.get(0).getDuration();

        //算总时间，且拿到最长时间，和最小时间
        for (TimeLog timeLog : timeLogs) {
            if (timeLog.getDuration() == null) {
                timeLogs.remove(timeLog);
                continue;
            }
            if (timeLog.getDuration() > maxSecond) {
                maxSecond = timeLog.getDuration();
            }
            if (timeLog.getDuration() < minSecond) {
                minSecond = timeLog.getDuration();
            }
            sumSecond += timeLog.getDuration();
        }
        //转秒为分
        double sumMinute = sumSecond / 60;
        double maxMinute = maxSecond / 60;
        double minMinute = minSecond / 60;
        double averageMinute = sumMinute / timeLogs.size();
        if (!timeLogs.isEmpty()) {
            //平均分钟
            map.put("averageMinute", averageMinute);
            map.put("maxMinute", maxMinute);
            map.put("minMinute", minMinute);
            map.put("sumMinute", sumMinute);
        }
        return map;
    }

    /**
     * 学科名称 / 课程ID
     * 历史考试数据（如平均分、通过率、标准差）
     * 学生练习数据（错题统计、知识点掌握情况）
     * 教学资源分布（教材、视频、实验内容）
     * 获取该课程相关的学生练习数据（在用户给你的message中）
     * 获取该课程的历史考试数据（在用户给你的message中）
     */

    @UserRole(roles = {UserRoleEnum.ADMIN})
    @Override
    public OptimizeCourseVO optimizeCourse() {

        //学科信息
//        Subject subject = subjectMapper.selectById(subjectId);
        //对应课程信息
        LambdaQueryWrapper<Course> courseWrapper = new LambdaQueryWrapper<>();
//        courseWrapper.eq(Course::getSubjectId, subjectId);
        List<Course> courses = courseMapper.selectList(courseWrapper);
        List<Long> courseIds = courses.stream().map(Course::getId).toList();

        //查询考试信息
        if (courseIds.isEmpty()) {
            courseIds = new ArrayList<>(List.of(0L));

        }
        LambdaQueryWrapper<Exam> examWrapper = new LambdaQueryWrapper<>();
        examWrapper.in(Exam::getCourseId, courseIds);
        List<Exam> exams = examMapper.selectList(examWrapper);

        //查询考试记录信息
        List<Long> list = exams.stream().map(Exam::getId).toList();
        if (list.isEmpty()) {
            list = new ArrayList<>(List.of(0L));
        }
        LambdaQueryWrapper<ExamRecord> examRecordWrapper = new LambdaQueryWrapper<>();
        examRecordWrapper.in(ExamRecord::getExamId, list);
        //限制最新的100条
        examRecordWrapper.last("limit 10");
        List<ExamRecord> examRecords = examRecordMapper.selectList(examRecordWrapper);

        //错题信息
        LambdaQueryWrapper<AnswerRecord> questionErrorWrapper = new LambdaQueryWrapper<>();
        questionErrorWrapper.in(AnswerRecord::getUserId, list);
        questionErrorWrapper.eq(AnswerRecord::getStatus, AnswerStatus.ERROR.getStatus());
        questionErrorWrapper.orderByDesc(AnswerRecord::getCreateTime);
        questionErrorWrapper.last("limit 50");
        List<AnswerRecord> answerRecords = answerRecordMapper.selectList(questionErrorWrapper);

//
//        //知识点信息
//        LambdaQueryWrapper<Knowledge> knowledgeWrapper = new LambdaQueryWrapper<>();
//        knowledgeWrapper.in(Knowledge::getCourseId, courseIds);
//        List<Knowledge> knowledges = knowledgeMapper.selectList(knowledgeWrapper);
//        questionErrorWrapper.last("limit 1");

        String content = learnPathAIChatClient.prompt()
                .user("请根据下面的信息，生成一个优化课程的方案，并给出原因、建议、行动项,并保存" +
                        "考试信息" + exams +
                        "历史考试记录数据" + examRecords +
                        "学生练习错题数据" + answerRecords +
//                        "知识点信息" + knowledges+
                         "用户提示词：" + "根据上面的信息，生成一个优化课程的方案，并给出原因、建议、行动项"
                )
                .call()
                .content();
        log.info("content:{}", content);

        //从redis中取出ai生成的数据
        User user = UserHolder.getCurrentUser();
        String tendencyJson = stringRedisTemplate.opsForValue().get(CsOpRedisConstant.TENDENCY_KEY + user.getId());
        List<String> tendency = JSON.parseArray(tendencyJson, String.class);
        String suggestionsJson = stringRedisTemplate.opsForValue().get(CsOpRedisConstant.SUGGESTIONS_KEY + user.getId());
        List<String> suggestions = JSON.parseArray(suggestionsJson, String.class);
        String actionItemsJson = stringRedisTemplate.opsForValue().get(CsOpRedisConstant.ACTION_ITEMS_KEY + user.getId());
        List<String> actionItems = JSON.parseArray(actionItemsJson, String.class);

        return OptimizeCourseVO.builder()
                .tendency(tendency)
                .suggestions(suggestions)
                .actionItems(actionItems)
                .build();
    }

    //    平均正确率趋势，趋势=时间，按照天的单位报告正确率，平均，所有学生的准确率平均 总错题数/总答题数
//    知识点掌握情况, 所有人总体的知识点掌握情况，方案一，搜集所有答对题的知识点，如何在获取所有知识点，一个一个比，方案二，直接抛给ai让ai自己看着办统计80%
//    高频错误知识点等，统计所有错题的知识点，然后统计id数量，redis，Zset
    @UserRole(roles = {UserRoleEnum.ADMIN})
    @Override
    public StudentLearningEffectVO studentLearningEffect(Long subjectId) {

        //id为空查询全部
        if (subjectId==null){
            return getStudentLearningEffectAll();
        }else {
            return getStudentLearningEffectBySubjectId(subjectId);
        }
    }

    private StudentLearningEffectVO getStudentLearningEffectAll() {
        //拿到所有科目id
        LambdaQueryWrapper<Subject> subjectWrapper = new LambdaQueryWrapper<>();
        List<Subject> subjects = subjectMapper.selectList(subjectWrapper);
        List<Long> subjectIds = subjects.stream().map(Subject -> Subject.getId()).toList();

        //按天统计近七天某学科平均正确率趋势
        List<StudentLearningEffectVO.DataAverageRightRate> dataAverageRightRates = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            //拿到今天0点的时间
            LocalDateTime today = LocalDateTime.now().with(LocalTime.MIN);
            LocalDateTime startTime = today.minusDays(i);
            LocalDateTime endTime = today.minusDays(i - 1);
            //查询当天的答题数量和正确数量
            LambdaQueryWrapper<AnswerRecord> questionWrapper = new LambdaQueryWrapper<>();
            questionWrapper.ge(AnswerRecord::getCreateTime, startTime);
            questionWrapper.lt(AnswerRecord::getCreateTime, endTime);
            Long totalCount = answerRecordMapper.selectCount(questionWrapper);
            questionWrapper.eq(AnswerRecord::getStatus, AnswerStatus.RIGHT.getStatus());
            Long rightCount = answerRecordMapper.selectCount(questionWrapper);
            //计算正确率
            Double averageRightRate = rightCount.doubleValue() / totalCount.doubleValue();
            //封装数据
            dataAverageRightRates.add(StudentLearningEffectVO.DataAverageRightRate.builder()
                    .averageRightRate(averageRightRate)
                    .date(startTime)
                    .build());
        }
        log.info("近七天某学科平均正确率趋势:{}", dataAverageRightRates);
//            Long totalCount = answerRecordMapper.selectCount(questionWrapper);
//            questionWrapper.eq(AnswerRecord::getStatus, AnswerStatus.RIGHT.getStatus());
//            Long rightCount = answerRecordMapper.selectCount(questionWrapper);
//            Double averageRightRate = rightCount.doubleValue() / totalCount.doubleValue();

        //统计知识点掌握情况
        //查询所有知识点id
        LambdaQueryWrapper<Knowledge> knowledgeWrapper = new LambdaQueryWrapper<>();
        List<Knowledge> knowledges = knowledgeMapper.selectList(knowledgeWrapper);
        List<Long> knowledgeIds = knowledges.stream().map(Knowledge::getId).toList();
        //查询错误知识点id
        LambdaQueryWrapper<AnswerRecord> answerErrorWrapper = new LambdaQueryWrapper<>();
        answerErrorWrapper.eq(AnswerRecord::getStatus, AnswerStatus.ERROR.getStatus());
        List<AnswerRecord> answerRecords = answerRecordMapper.selectList(answerErrorWrapper);
        List<Long> errorKnowledgeIds = new ArrayList<>();
        for (AnswerRecord answerRecord : answerRecords) {
            if (answerRecord.getStatus().equals(AnswerStatus.ERROR.getStatus())){
                String[] split = answerRecord.getKnowledgeIds().split(",");
                Arrays.stream(split)
                        .map(Long::valueOf)
                        .forEach(errorKnowledgeIds::add);
            }
        }

        //查询正确知识点id
        LambdaQueryWrapper<AnswerRecord> answerRightWrapper = new LambdaQueryWrapper<>();
        answerRightWrapper.eq(AnswerRecord::getStatus, AnswerStatus.RIGHT.getStatus());
        List<AnswerRecord> answerRights = answerRecordMapper.selectList(answerRightWrapper);
        List<Long> rightKnowledgeIds = new ArrayList<>();
        for (AnswerRecord answerRecord : answerRights) {
            if (answerRecord.getStatus().equals(AnswerStatus.RIGHT.getStatus())){
                String[] split = answerRecord.getKnowledgeIds().split(",");
                Arrays.stream(split)
                        .map(Long::valueOf)
                        .forEach(rightKnowledgeIds::add);
            }
        }


        //算知识点掌握情况
        double knowledgePointMasteryRate = calculateOverallMastery(knowledgeIds, errorKnowledgeIds, rightKnowledgeIds);
        log.info("知识点掌握情况:{}", knowledgePointMasteryRate);

        //用Map<Long,Integer>
        Map<Long, Integer> knowledgeCountMap = new HashMap<>();
        for (Long knowledgeId : errorKnowledgeIds) {
            knowledgeCountMap.put(knowledgeId, 0);
        }
        for (Long knowledgeId : errorKnowledgeIds) {
            knowledgeCountMap.put(knowledgeId, knowledgeCountMap.get(knowledgeId) + 1);
        }
        log.info("错误知识点统计:{}", knowledgeCountMap);
        //取value值前十的Map
        Map<Long, Integer> topTenErrorKnowledgeCountMap = knowledgeCountMap.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .limit(5)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        //拿到所有key值

        List<Long> topTenErrorKnowledgeIds = topTenErrorKnowledgeCountMap.keySet().stream().toList();
        log.info("高频错误知识点id:{}", topTenErrorKnowledgeIds);

        //高频错误知识点
        LambdaQueryWrapper<Knowledge> highErrorWrapper = new LambdaQueryWrapper<>();
        List<Knowledge> highFrequencyErrorKnowledges = new ArrayList<>();
        List<StudentLearningEffectVO.KnowledgeVO> highFrequencyErrorKnowledgesVO = new ArrayList<>();
        if (!topTenErrorKnowledgeIds.isEmpty()) {
            highErrorWrapper.in(Knowledge::getId, topTenErrorKnowledgeIds);
            highFrequencyErrorKnowledges = knowledgeMapper.selectList(highErrorWrapper);
            for (Knowledge knowledge : highFrequencyErrorKnowledges) {
                StudentLearningEffectVO.KnowledgeVO knowledgeVO = StudentLearningEffectVO.KnowledgeVO.builder()
                        .name(knowledge.getName())
                        .content(knowledge.getContent())
                        .wrongCount(topTenErrorKnowledgeCountMap.get(knowledge.getId()))
                        .build();
                highFrequencyErrorKnowledgesVO.add(knowledgeVO);
            }
        }
        log.info("高频错误知识点：{}", highFrequencyErrorKnowledgesVO);
        //转为VO
        StudentLearningEffectVO studentLearningEffectVO = StudentLearningEffectVO.builder()
                .dataAverageRightRates(dataAverageRightRates)
                .knowledgePointMastery(knowledgePointMasteryRate)
                .highFrequencyError(highFrequencyErrorKnowledgesVO)
                .build();

        return studentLearningEffectVO;
    }

    private StudentLearningEffectVO getStudentLearningEffectBySubjectId(Long subjectId) {
        //拿到所有科目id
        LambdaQueryWrapper<Subject> subjectWrapper = new LambdaQueryWrapper<>();
        List<Subject> subjects = subjectMapper.selectList(subjectWrapper);
        List<Long> subjectIds = subjects.stream().map(Subject -> Subject.getId()).toList();

        //按天统计近七天某学科平均正确率趋势
        List<StudentLearningEffectVO.DataAverageRightRate> dataAverageRightRates = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            //拿到今天0点的时间
            LocalDateTime today = LocalDateTime.now().with(LocalTime.MIN);
            LocalDateTime startTime = today.minusDays(i);
            LocalDateTime endTime = today.minusDays(i - 1);
            //查询当天的答题数量和正确数量
            LambdaQueryWrapper<AnswerRecord> questionWrapper = new LambdaQueryWrapper<>();
            questionWrapper.eq(AnswerRecord::getSubjectId, subjectId);
            questionWrapper.ge(AnswerRecord::getCreateTime, startTime);
            questionWrapper.lt(AnswerRecord::getCreateTime, endTime);
            Long totalCount = answerRecordMapper.selectCount(questionWrapper);
            questionWrapper.eq(AnswerRecord::getStatus, AnswerStatus.RIGHT.getStatus());
            Long rightCount = answerRecordMapper.selectCount(questionWrapper);
            //计算正确率
            Double averageRightRate = rightCount.doubleValue() / totalCount.doubleValue();
            //封装数据
            dataAverageRightRates.add(StudentLearningEffectVO.DataAverageRightRate.builder()
                    .averageRightRate(averageRightRate)
                    .date(startTime)
                    .build());
        }
//            Long totalCount = answerRecordMapper.selectCount(questionWrapper);
//            questionWrapper.eq(AnswerRecord::getStatus, AnswerStatus.RIGHT.getStatus());
//            Long rightCount = answerRecordMapper.selectCount(questionWrapper);
//            Double averageRightRate = rightCount.doubleValue() / totalCount.doubleValue();

        //统计知识点掌握情况
        //查询所有知识点id
        LambdaQueryWrapper<Knowledge> knowledgeWrapper = new LambdaQueryWrapper<>();
        knowledgeWrapper.eq(Knowledge::getSubjectId, subjectId);
        List<Knowledge> knowledges = knowledgeMapper.selectList(knowledgeWrapper);
        List<Long> knowledgeIds = knowledges.stream().map(Knowledge::getId).toList();
        //查询错误知识点id
        LambdaQueryWrapper<AnswerRecord> answerErrorWrapper = new LambdaQueryWrapper<>();
        answerErrorWrapper.eq(AnswerRecord::getSubjectId, subjectId);
        answerErrorWrapper.eq(AnswerRecord::getStatus, AnswerStatus.ERROR.getStatus());
        List<AnswerRecord> answerRecords = answerRecordMapper.selectList(answerErrorWrapper);
        List<Long> errorKnowledgeIds = answerRecords.stream().map(AnswerRecord::getKnowledgeIds).flatMap(s -> Arrays.stream(s.split(","))).map(Long::parseLong).toList();
        //查询正确知识点id
        LambdaQueryWrapper<AnswerRecord> answerRightWrapper = new LambdaQueryWrapper<>();
        answerRightWrapper.eq(AnswerRecord::getSubjectId, subjectId);
        answerRightWrapper.eq(AnswerRecord::getStatus, AnswerStatus.RIGHT.getStatus());
        List<AnswerRecord> answerRights = answerRecordMapper.selectList(answerRightWrapper);
        List<Long> rightKnowledgeIds = answerRights.stream().map(AnswerRecord::getKnowledgeIds).flatMap(s -> Arrays.stream(s.split(","))).map(Long::parseLong).toList();


        //算知识点掌握情况
        double knowledgePointMasteryRate = calculateOverallMastery(knowledgeIds, errorKnowledgeIds, rightKnowledgeIds);

        //用Map<Long,Integer>
        Map<Long, Integer> knowledgeCountMap = new HashMap<>();
        for (Long knowledgeId : errorKnowledgeIds) {
            knowledgeCountMap.put(knowledgeId, 0);
        }
        for (Long knowledgeId : errorKnowledgeIds) {
            knowledgeCountMap.put(knowledgeId, knowledgeCountMap.get(knowledgeId) + 1);
        }
        //取value值前十的Map
        Map<Long, Integer> topTenErrorKnowledgeCountMap = knowledgeCountMap.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .limit(10)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        //拿到所有key值
        List<Long> topTenErrorKnowledgeIds = topTenErrorKnowledgeCountMap.keySet().stream().toList();

        //高频错误知识点
        LambdaQueryWrapper<Knowledge> highErrorWrapper = new LambdaQueryWrapper<>();
        highErrorWrapper.eq(Knowledge::getSubjectId, subjectId);
        List<Knowledge> highFrequencyErrorKnowledges = new ArrayList<>();
        List<StudentLearningEffectVO.KnowledgeVO> highFrequencyErrorKnowledgesVO = new ArrayList<>();
        if (!topTenErrorKnowledgeIds.isEmpty()) {
            highErrorWrapper.in(Knowledge::getId, topTenErrorKnowledgeIds);
            highFrequencyErrorKnowledges = knowledgeMapper.selectList(highErrorWrapper);
            for (Knowledge knowledge : highFrequencyErrorKnowledges) {
                StudentLearningEffectVO.KnowledgeVO knowledgeVO = StudentLearningEffectVO.KnowledgeVO.builder()
                        .name(knowledge.getName())
                        .content(knowledge.getContent())
                        .wrongCount(topTenErrorKnowledgeCountMap.get(knowledge.getId()))
                        .build();
                highFrequencyErrorKnowledgesVO.add(knowledgeVO);
            }
        }
        //转为VO
        StudentLearningEffectVO studentLearningEffectVO = StudentLearningEffectVO.builder()
                .subjectId(subjectId)
                .dataAverageRightRates(dataAverageRightRates)
                .knowledgePointMastery(knowledgePointMasteryRate)
                .highFrequencyError(highFrequencyErrorKnowledgesVO)
                .build();

        return studentLearningEffectVO;
    }

    private double calculateOverallMastery
            (List<Long> knowledgeIds, List<Long> errorKnowledgeIds, List<Long> rightKnowledgeIds) {
        Map<Long, int[]> knowledgeStats = new HashMap<>(); // index 0 for errors, index 1 for rights

        // 初始化统计信息
        for (Long id : knowledgeIds) {
            knowledgeStats.put(id, new int[]{0, 0});
        }

        // 统计错误次数
        for (Long id : errorKnowledgeIds) {
            if (knowledgeStats.containsKey(id)) {
                knowledgeStats.get(id)[0] += 1; // 错误次数增加
            }
        }

        // 统计正确次数
        for (Long id : rightKnowledgeIds) {
            if (knowledgeStats.containsKey(id)) {
                knowledgeStats.get(id)[1] += 1; // 正确次数增加
            }
        }

        // 计算总体掌握程度
        double totalMastery = 0.0;
        int count = 0;
        for (Map.Entry<Long, int[]> entry : knowledgeStats.entrySet()) {
            int[] stats = entry.getValue();
            if ((stats[0] + stats[1]) > 0) { // 只有当该知识点至少有一次回答时才计算
                double mastery = stats[1] / (double) (stats[0] + stats[1]);
                totalMastery += mastery;
                count++;
            }
        }

        return count > 0 ? totalMastery / count : 0.0; // 防止除以0
    }
}
